#pragma once
#include<iostream>
#include<string>
#include<queue>
#include<vector>
#include<memory>
#include"log.hpp"
#include"Thread.hpp"
const static int default_thread_num = 5;
using thread_t = std::shared_ptr<My_thread::Thread>;
void Test()
{
    while(true){
        LOG(log_level::DEBUG)<<"i am a test function";
        sleep(5);
        break;
    }
}
//T类型是任务函数的类型
template<typename T>//单例模式
class ThreadPool {
    private:
        bool IsEmpty()
        {
            return _taskq.empty();
        }
        void HandleTask(std::string name)//拿任务，处理任务
        {
            LOG(log_level::INFO)<<name<<" join in the handleTask function";
            while(true){
                T task;
                {
                    My_thread::LockGuard lock(_lock);
                    while(IsEmpty() && _is_running){//while防止伪唤醒
                        _wait_num++;
                        _cond.Wait(_lock);//释放锁，等待任务
                        _wait_num--;    
                    }
                    if(!_is_running && IsEmpty()) break;
                    task = _taskq.front();
                    _taskq.pop();

                }
                //处理任务
                task();//调用任务函数
            }
            LOG(log_level::INFO)<<name<<" left the handleTask function";
        }
        ThreadPool(const ThreadPool<T>&) = delete;
        ThreadPool<T>& operator=(const ThreadPool<T>&) = delete;

        ThreadPool(int num = default_thread_num) : _num(num), _wait_num(0)
        {
            for(int i = 0; i < _num; i++){
                // _threads.push_back(std::make_shared<My_thread::Thread>(Test));//测试
                _threads.push_back(std::make_shared<My_thread::Thread>(std::bind(&ThreadPool::HandleTask, this,std::placeholders::_1)));//创建线程
                LOG(log_level::INFO)<<"create a thread: "<<_threads[i]->GetName() <<" sucessfully";
            }
        }

    public:
        static ThreadPool<T>* getinstance()//饿汉模式
        {
            if(instance == nullptr){
                My_thread::LockGuard lock(instance_lock);//加锁
                if(instance == nullptr){
                    LOG(log_level::INFO)<<"单例首次执行,需要创建实例";
                    instance = new ThreadPool<T>();
                    instance->start();
                }
            }
            return instance;
        }
        void start()
        {
            if(_is_running) return;
            _is_running = true;
            for(auto& thread : _threads){
                thread->Run();
                LOG(log_level::INFO)<<"satrt a thread: "<<thread->GetName() <<" sucessfully";
            }
        }
        void pushTask(T task)
        {
            My_thread::LockGuard lock(_lock);
            if(!_is_running) return;
            _taskq.push(task);
            if(_wait_num > 0){
                _cond.Signal();//唤醒一个线程
            }
        }
        void wait()
        {
            for(auto& thread : _threads){
                thread->Join();
                LOG(log_level::INFO)<<"wait a thread: "<<thread->GetName() <<" sucessfully";

            }
        }
        void stop()
        {
            My_thread::LockGuard lock(_lock);
            if(_is_running){//线程自己退出(阻塞的需要唤醒)，历史的任务被处理，不能再加入新的任务
                _is_running = false;//设置停止标志
                if(_wait_num > 0){
                    _cond.Broadcast();//唤醒所有线程
                }
            }
        }
        ~ThreadPool()
        {

        }
    private:
        int _num;
        int _wait_num;
        bool _is_running = false;
        std::queue<T> _taskq;//任务队列（临界资源） 
        std::vector<thread_t> _threads;
        My_thread::Mutex _lock;
        My_thread::Cond _cond;
        static ThreadPool<T> *instance;//静态成员变量
        static My_thread::Mutex instance_lock;//静态成员锁,用来保护单例
};
template<typename T>
ThreadPool<T> *ThreadPool<T>::instance = nullptr;//静态成员在类外初始化

template<typename T>
My_thread::Mutex ThreadPool<T>::instance_lock;